import { getCurrentInstance } from 'vue';
import { mountComponent, usePopupState } from '../utils';
import FanToast from './toast.vue';

interface optionsType {
  message?: string;
  icon?: 'none' | 'success' | 'error' | 'loading';
  duration?: number;
  delay?: number;
  mask?: boolean;
}

const defaultOptions: optionsType = {
  message: '',
  icon: 'none',
  duration: 2000,
  delay: 0,
  mask: true,
};

let queue: any;

function parseOptions(message: optionsType | string) {
  if (typeof message === 'object') return message;
  return { message: message ? String(message) : '' };
}

function createInstance() {
  const { instance } = mountComponent({
    setup() {
      const { open, state, close, toggle } = usePopupState();

      const render = () => {
        return <FanToast {...state} onUpdate:show={toggle} />;
      };

      (getCurrentInstance() as any).render = render;

      return {
        open,
        close,
      };
    },
  });
  return instance;
}

function getInstance() {
  if (!queue) {
    const instance = createInstance();
    queue = instance;
  }
  return queue;
}

const create = (
  options: optionsType | string,
  o: optionsType = { icon: 'none' },
) => {
  clear();

  const toast = getInstance();

  const parsedOptions = parseOptions(options);

  toast.open({ ...defaultOptions, ...parsedOptions, ...o });

  return toast;
};

export const toast = (options: optionsType | string) => create(options);

toast.success = (options: optionsType | string) => {
  create(options, { icon: 'success' });
};

toast.error = (options: optionsType | string) => {
  create(options, { icon: 'error' });
};

toast.loading = (options: optionsType | string) => {
  create(options, { icon: 'loading', duration: 0 });
};

const clear = async () => {
  if (queue) {
    queue.close();
    queue = null;
  }
};

toast.clear = clear;
